package com.project.control.ftp;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.ftp.Ftp;
import com.project.bean.FtpFileBean;
import com.project.control.BaseController;
import com.project.service.FtpService;
import com.project.utils.FtpDownLoadUtils;
import com.project.utils.layui.PageUtils;
import com.project.utils.result.ResultModel;
import com.project.utils.result.ResultTools;
import com.project.utils.token.CheckToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author : Mr.Yan
 * @program : com.project.control.ftp
 * @create : 2020/07/13
 * @description : ftp控制层
 */
@Slf4j
@RestController
@RequestMapping(value = "ftp")
public class FtpController extends BaseController {

    @Autowired
    private FtpProperties ftpProperties;

    @Autowired
    private FtpService ftpService;

    /**
     * @author : Mr.Yan
     * @create : 2020/7/13
     * @description : 展示目录
     */
    @CheckToken
    @GetMapping(value = "/list")
    public ResultModel lsList(PageUtils pageUtils) {
        Map<String, Object> paramMap = (Map<String, Object>) pageUtils.getParas();
        Ftp ftp = ftpService.ftpLogin(ftpProperties.getHost(), ftpProperties.getPort(), ftpProperties.getUser(), ftpProperties.getPassword());
        if (ObjectUtil.isNotNull(ftp)) { // ftp不为null则表示登陆成功，否则登陆失败
            String remoteFolder = ftpProperties.getRemoteFolder();
            if (paramMap.size() > 0) {
                String suffixFolder = paramMap.get("suffixFolder").toString();
                if (StrUtil.isNotEmpty(suffixFolder)) {
                    remoteFolder += suffixFolder;
                }
            }
            FTPFile[] ftpFiles = ftpService.ftplsFiles(ftp, remoteFolder);
            PageQuery<FTPFile> pageQuery = new PageQuery();
            List<FtpFileBean> ftpFileList = new ArrayList<>();
            for (FTPFile ftpFile : ftpFiles) {
                FtpFileBean ftpFileBean = new FtpFileBean();
                ftpFileBean.setName(ftpFile.getName());
                ftpFileBean.setDirectory(ftpFile.isDirectory());
                ftpFileBean.setFile(ftpFile.isFile());
                ftpFileBean.setSize(ftpFile.getSize());
                ftpFileBean.setTimestamp(ftpFile.getTimestamp());
                ftpFileList.add(ftpFileBean);
            }
            pageQuery.setList(ftpFileList);
            pageQuery.setTotalRow(ftpFileList.size());
            ftpService.ftpClose(ftp);
            return ResultTools.success(pageQuery);
        }

        return ResultTools.fail("未连接到FTP，用户名或密码错误");
    }

    /**
     * @author : Mr.Yan
     * @create : 2020/7/14
     * @description : 新建文件夹 { folderName: 文件夹名称，folderPath: 文件夹路径 }
     */
    @CheckToken
    @PostMapping(value = "newFolder")
    public ResultModel newFolder(@RequestParam String folderName, @RequestParam String folderPath) {
        Ftp ftp = ftpService.ftpLogin(ftpProperties.getHost(), ftpProperties.getPort(), ftpProperties.getUser(), ftpProperties.getPassword());
        folderName = ftpService.newFolder(ftp, folderName, ftpProperties.getRemoteFolder() + folderPath);
        if (StrUtil.isEmpty(folderName)) {
            ftpService.ftpClose(ftp);
            return ResultTools.fail("创建失败");
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("name", folderName);
        resultMap.put("timestamp", System.currentTimeMillis());
        ftpService.ftpClose(ftp);
        return ResultTools.success(resultMap);
    }

    /**
     * @author : Mr.Yan
     * @create : 2020/7/14
     * @description : 删除文件 { type: 文件/文件夹,folderName: 文件夹名称，folderPath: 文件夹路径 }
     */
    @CheckToken
    @DeleteMapping(value = "delete")
    public ResultModel delete(@RequestParam String type, @RequestParam String name, @RequestParam String folderPath) {
        Ftp ftp = ftpService.ftpLogin(ftpProperties.getHost(), ftpProperties.getPort(), ftpProperties.getUser(), ftpProperties.getPassword());
        if (type.equals("file")) {
            boolean deleteFileBool = ftpService.deleteFile(ftp, name, ftpProperties.getRemoteFolder() + folderPath);
            if (deleteFileBool) {
                log.info(String.format("删除文件'%s'成功", name));
                ftpService.ftpClose(ftp);
                return ResultTools.success();
            }
        } else if (type.equals("dir")) {
            boolean deleteDirBool = ftpService.deleteDir(ftp, name, ftpProperties.getRemoteFolder() + folderPath);
            if (deleteDirBool) {
                log.info(String.format("删除文件夹'%s'成功", name));
                ftpService.ftpClose(ftp);
                return ResultTools.success();
            }
        }
        log.info(String.format("删除文件夹'%s'失败", name));
        ftpService.ftpClose(ftp);
        return ResultTools.fail();
    }

    /**
     * @author : Mr.Yan
     * @create : 2020/7/14
     * @description : 重命名
     */
    @CheckToken
    @PostMapping(value = "rename")
    public ResultModel rename(@RequestParam String srcName, @RequestParam String toName, @RequestParam String folderPath) {
        Ftp ftp = ftpService.ftpLogin(ftpProperties.getHost(), ftpProperties.getPort(), ftpProperties.getUser(), ftpProperties.getPassword());
        boolean rename = ftpService.rename(ftp, srcName, toName, ftpProperties.getRemoteFolder() + folderPath);
        if (rename) {
            ftpService.ftpClose(ftp);
            log.info(String.format("重命名'%s'成功", srcName));
            return ResultTools.success();
        }
        ftpService.ftpClose(ftp);
        log.info(String.format("重命名'%s'失败", srcName));
        return ResultTools.fail();
    }

    /**
     * @author : Mr.Yan
     * @create : 2020/7/14
     * @description : 下载文件/文件夹 { type: 文件/文件夹,folderName: 文件夹名称，folderPath: 文件夹路径 }
     */
    @CheckToken
    @GetMapping(value = "download")
    public void download(@RequestParam String type, @RequestParam String name, @RequestParam String folderPath) throws IOException {
        Ftp ftp = ftpService.ftpLogin(ftpProperties.getHost(), ftpProperties.getPort(), ftpProperties.getUser(), ftpProperties.getPassword());
        if (type.equals("file")) {
            ftpService.downloadFile(ftp, name, ftpProperties.getRemoteFolder() + folderPath, super.getRequest());
        }
        ftpService.ftpClose(ftp);
    }

    /**
      * @author : Mr.Yan
      * @create : 2020/7/15
      * @description : 上传文件
      */
    @CheckToken
    @PostMapping (value = "updateFile")
    public ResultModel updateFile (@RequestParam MultipartFile file, @RequestParam String folderPath) {
        Ftp ftp = ftpService.ftpLogin(ftpProperties.getHost(), ftpProperties.getPort(), ftpProperties.getUser(), ftpProperties.getPassword());
        String fileName = ftpService.updateFile(ftp, file, ftpProperties.getRemoteFolder() + folderPath);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("name", fileName);
        resultMap.put("size", file.getSize());
        resultMap.put("directory",false);
        resultMap.put("file",true);
        resultMap.put("timestamp", System.currentTimeMillis());
        if (StrUtil.isNotEmpty(fileName)) {
            log.info(String.format("上传文件'%s'成功", file.getOriginalFilename()));
            ftpService.ftpClose(ftp);
            return ResultTools.success(resultMap);
        }
        ftpService.ftpClose(ftp);
        return ResultTools.fail();
    }

    /**
      * @author : Mr.Yan
      * @create : 2020/7/16
      * @description : 文件的断点下载
      */
    @CheckToken
    @GetMapping (value = "fileDowlond")
    public void fileDowload (@RequestParam String type, @RequestParam String name, @RequestParam String folderPath) throws IOException {
        // 首先获取文件
        Ftp ftp = ftpService.ftpLogin(ftpProperties.getHost(), ftpProperties.getPort(), ftpProperties.getUser(), ftpProperties.getPassword());
        FTPClient ftpClient = ftp.getClient();
        new FtpDownLoadUtils().download(ftpClient,ftpProperties.getRemoteFolder() + folderPath, name, super.getRequest());
    }

    /**
      * @author : Mr.Yan
      * @create : 2020/7/17
      * @description : 获取进度条进度
      */
    @CheckToken
    @GetMapping (value = "findProcess")
    public ResultModel findProcess (@RequestParam String name) {
        Object obj = super.getSession("process" + name);
        if (ObjectUtil.isNull(obj)) {
            return ResultTools.fail();
        }
        return ResultTools.success(obj);

    }



}
